﻿using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;

namespace xres
{


    public abstract class BaseAsyncAction : IEnumerator
    {
        
        class ActionWithData
        {
            public object userData;
            public Action<object, string, object> action;

            public ActionWithData(Action<object, string, object> action)
            {
                this.action = action;
            }

            public ActionWithData(Action<object, string, object> action, object userData)
            {
                this.action = action;
                this.userData = userData;
            }

        }

        public class OnCompleteEvent
        {
            List<ActionWithData> _list = new List<ActionWithData>();

            bool CheckExist(Action<object, string, object> listener, object userData)
            {
                for (var i = 0; i < _list.Count; ++i)
                {
                    var item = _list[i];
                    if (item.action == listener && null == item.userData)
                        return true; //已经存在
                }

                return false;
            }

            public void AddListener(Action<object, string, object> listener)
            {
                if (!CheckExist(listener, null))
                    _list.Add(new ActionWithData(listener));
            }

            public void AddListenerWithData(Action<object, string, object> listener, object userData)
            {
                if (!CheckExist(listener, userData))
                    _list.Add(new ActionWithData(listener, userData));
            }

            public void RemoveListener(Action<object, string, object> listener)
            {
                for (var i = 0; i < _list.Count; ++i)
                {
                    var item = _list[i];
                    if (listener == item.action)
                    {
                        _list.RemoveAt(i);
                    }
                }
            }

            public void Invoke(object sender)
            {
                for (var i = 0; i < _list.Count; ++i)
                {
                    var item = _list[i];
                    item.action.Invoke(sender, "", item.userData);
                }
                _list.Clear();
            }
        }

        internal protected string _state = BaseAsyncActionState.Init;
        public string State { get { return _state; } }

        public readonly OnCompleteEvent onComplete = new OnCompleteEvent();

        //public object UserData { private get; set; }


        public string ErrMsg { get; internal set; }

        public string ErrType { get; internal set; }

        protected void SetError(string type, string msg)
        {
            ErrType = type;
            ErrMsg = msg;
        }

        public virtual bool IsLoadFinish()
        {
            return BaseAsyncActionState.Finish == _state;
        }

        //public float CheckProgress() { return 1f; }

        protected void SetFinishAndNotify(string error, string typeStr = "")
        {
            _state = BaseAsyncActionState.Finish;
            NotifyComplete(typeStr);
        }

        protected void NotifyComplete(string typeStr)
        {
            try
            {
                onComplete.Invoke(this);
            }
            catch (Exception ex)
            {
                Debug.LogWarning($"msg: {ex.Message}, st: {ex.StackTrace}");
            }
        }


        public object Current { get { return null; } }

        public bool MoveNext()
        {
            return !IsLoadFinish();
        }

        public void Reset()
        {
            //do nothing
        }

    } //end of class


}
